package com.example.bootintegration.redisson;

import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedissonDelayQueue {

    private RedissonClient redissonClient;

    private RDelayedQueue<String> delayQueue;
    private RBlockingQueue<String> blockingQueue;
    private String KEY_LOCKED = "test_locked";

    // @PostConstruct
    // public void init() {
    //     initDelayQueue();
    //     startDelayQueueConsumer();
    //     lock2();
    // }

    private void initDelayQueue() {
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer();
        serverConfig.setAddress("redis://localhost:6379");
        redissonClient = Redisson.create(config);

        blockingQueue = redissonClient.getBlockingQueue("SANYOU");
        delayQueue = redissonClient.getDelayedQueue(blockingQueue);
    }

    private void startDelayQueueConsumer() {
        new Thread(() -> {
            while (true) {
                try {
                    String task = blockingQueue.take();
                    log.info("接收到延迟任务:{}", task);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "SANYOU-Consumer").start();
    }

    public void offerTask(String task, long seconds) {
        log.info("添加延迟任务:{} 延迟时间:{}s", task, seconds);
        delayQueue.offer(task, seconds, TimeUnit.SECONDS);
    }


    public void lock2() {

        for (int i = 0; i < 3; i++) {
            final int index = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    log.info(Thread.currentThread().getName() + " \t 运行");
                    RLock lock1 = redissonClient.getLock(KEY_LOCKED);
                    try {
                        // 尝试获取7s
//                        boolean b = lock1.tryLock(7,  TimeUnit.SECONDS);
                        // 尝试获取锁7s, 最多占有锁2s，超过后自动释放，调用unlock可以提前释放。
                        boolean b = lock1.tryLock(7, 2, TimeUnit.SECONDS);
                        if (!b) {
                            log.info(Thread.currentThread().getName() + " \t 获取锁失败");
                            return;
                        }
                    } catch (InterruptedException e) {
                    }

                    log.info(Thread.currentThread().getName() + " \t 获取锁");

                    try {
                        // 模拟处理逻辑用时
                        Thread.sleep((index * 2) * 1000);
                    } catch (InterruptedException e) {

                    }

                    // 如果是当前线程持有锁，手动释放
                    if (lock1.isHeldByCurrentThread()) {
                        lock1.unlock();
                        log.info(Thread.currentThread().getName() + " \t 释放锁");
                    }
                }
            }).start();
        }
    }

}